﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

using Declarations;
using Declarations.Events;
using Declarations.Media;
using Declarations.Players;
using Implementation;

namespace SDK10kWrapper
{
    partial class CameraBox
    {

        #region STATIC MEMBERS
        #region Static Variable
        /// <summary>
        /// Private List for all instance of this CameraBox class
        /// </summary>
        static List<CameraBox> cList = new List<CameraBox>();

        /// <summary>
        /// Private Dict to store Multiple Instance bind to One Trackbar
        /// </summary>
        static Dictionary<TrackBar, List<CameraBox>> tcDict = new Dictionary<TrackBar, List<CameraBox>>();

        //static int m_count = 0; No need, use cList instead
        public static int Count { get { return cList.Count; } }
        static readonly object locker = new object();
        static long MaxDuration;
        static CameraBox MaxCamera;

        //public static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        #endregion
        #region Static Method
        /// <summary>
        /// Play all Camera in this Form
        /// </summary>
        /// <param name="form">The Form that contain all of the CameraBox</param>
        public static void PlayAll(Form form)
        {
            List<CameraBox> synclist = new List<CameraBox>(); // A list of camerabox in Offline Mode need to sync Play
            foreach (CameraBox cam in cList)
            {
                if (cam.ParentForm == form)
                {
                    if (cam.InvokeRequired)
                        cam.Invoke((MethodInvoker)delegate() // No BeginInvoke since need to wait until all the setting are done
                        {   // If same this Form then Play
                            cam.Play();
                            if (cam._CameraMode == CameraMode.Offline)
                            {   // Synchronize Step for all CameraBox in this Form
                                //cam.m_player.Pause();
                                //cam.m_player.Time = 0;
                                synclist.Add(cam); // Crossthread or not ? this call
                            }
                        });
                    else
                    {
                        cam.Play();
                        if (cam._CameraMode == CameraMode.Offline)
                        {   // Synchronize Step for all CameraBox in this Form
                            //cam.m_player.Pause();
                            //cam.m_player.Time = 0;
                            synclist.Add(cam); // Crossthread or not ? this call
                        }
                    }
                }
            }

            foreach (CameraBox cam in synclist)
            {   // Synchronize HERE : by Start then Pause All then Move Time to ZERO then UnPause All
                if (cam.InvokeRequired) cam.Invoke((MethodInvoker)(() => cam.m_player.Position = 0)); // This will Unpause & start all altogether. If need clock sync then use netsync with loop IP : 127.0.0.1
                else cam.m_player.Position = 0;
            }
        }

        /// <summary>
        /// Pause all Camera in this Form
        /// </summary>
        /// <param name="form">The Form that contain all of the CameraBox</param>
        public static void PauseAll(Form form)
        {
            foreach (CameraBox cam in cList)
            {
                if (cam.ParentForm == form)
                {
                    if (cam.InvokeRequired) cam.Invoke((MethodInvoker)(() => cam.Pause()));
                    else cam.Pause();
                }
            }
        }

        /// <summary>
        /// Stop playing all the camera in this form
        /// </summary>
        /// <param name="form">The Form that contain all of the CameraBox</param>
        public static void StopAll(Form form)
        {
            foreach (CameraBox cam in cList)
            {
                if (cam.ParentForm == form)
                {
                    if (cam.InvokeRequired) cam.Invoke((MethodInvoker)(() => cam.Stop()));
                    else cam.Stop();
                }

            }
        }

        /// <summary>
        /// Capture (Take Snapshot) of all camera 's current Frame
        /// </summary>
        /// <param name="form">The Form that contain all of the CameraBox</param>
        public static void CaptureAll(Form form)
        {
            foreach (CameraBox cam in cList)
            {
                if (cam.ParentForm == form)
                {
                    if (cam.InvokeRequired) cam.Invoke((MethodInvoker)delegate() { cam.Capture(); });
                    else cam.Capture();
                }
            }
        }

        /// <summary>
        /// Change the Capture Folder of All Camera in this Form to new Location
        /// </summary>
        /// <param name="form">The Form that contain all of the CameraBox</param>
        /// <param name="folderPath">New Folder Path you want to change</param>
        public static void ChangeCaptureFolderAll(Form form, string folderPath)
        {
            foreach (CameraBox cam in cList)
            {
                if (cam.ParentForm == form)
                {
                    if (cam.InvokeRequired) cam.Invoke((MethodInvoker)delegate()
                    {
                        cam.CapturePath = Path.Combine(folderPath, Path.GetFileName(cam.CapturePath));
                    });
                    else cam.CapturePath = Path.Combine(folderPath, Path.GetFileName(cam.CapturePath));
                }
            }
        }

        /// <summary>
        /// Change CameraMode for all Camera in this Form
        /// </summary>
        /// <param name="form">The Form that contain all of the CameraBox</param>
        /// <param name="mode"></param>
        public static void ChangeModeAll(Form form, CameraMode mode)
        {
            foreach (CameraBox cam in cList)
            {
                if (cam.ParentForm == form)
                {
                    if (cam.InvokeRequired) cam.Invoke((MethodInvoker)delegate() { cam.CameraMode = mode; });
                    else cam.CameraMode = mode;
                }
            }
        }

        /// <summary>
        /// Connect all camera in this form to ACTI server
        /// </summary>
        /// <param name="form">The Form that contain all of the CameraBox</param>
        public static void ConnectAll(Form form)
        {
            foreach (CameraBox cam in cList)
            {
                if (cam.ParentForm == form)
                {
                    if (cam.InvokeRequired) cam.Invoke((MethodInvoker)delegate() { cam.Connect(); });
                    else cam.Connect();
                }
            }
        }

        /// <summary>
        /// Disconnect all camera in this form from ACTI server
        /// </summary>
        /// <param name="form">The Form that contain all of the CameraBox</param>
        public static void DisconnectAll(Form form)
        {
            foreach (CameraBox cam in cList)
            {
                if (cam.ParentForm == form)
                {
                    if (cam.InvokeRequired) cam.Invoke((MethodInvoker)delegate() { cam.Disconnect(); });
                    else cam.Disconnect();
                }
            }
        }

        /// <summary>
        /// Start recording all camera in this form
        /// </summary>
        /// <param name="form">The Form that contain all of the CameraBox</param>
        public static void StartRecordAll(Form form)
        {
            foreach (CameraBox cam in cList)
            {
                if (cam.ParentForm == form)
                {
                    if (cam.InvokeRequired) cam.Invoke((MethodInvoker)delegate() { cam.StartRecord(); });
                    else cam.StartRecord();
                }
            }
        }

        /// <summary>
        /// Change Recording Folder for all camera in this form to a new location
        /// </summary>
        /// <param name="form">The Form that contain all of the CameraBox</param>
        /// <param name="folderPath">New Folder Location to Change</param>
        public static void ChangeRecordFolderAll(Form form, string folderPath)
        {
            foreach (CameraBox cam in cList)
            {
                if (cam.ParentForm == form)
                {
                    if (cam.InvokeRequired) cam.Invoke((MethodInvoker)delegate()
                    {
                        cam.Online_VideoSavePath = Path.Combine(folderPath, Path.GetFileName(cam.Online_VideoSavePath));
                    });
                    else cam.Online_VideoSavePath = Path.Combine(folderPath, Path.GetFileName(cam.Online_VideoSavePath));
                }
            }
        }

        /// <summary>
        /// Stop Record All Camera in this form.
        /// </summary>
        /// <param name="form">The Form that contain all of the CameraBox</param>
        /// <returns>null if no file recorded otherwise a dictionary</returns>
        public static Dictionary<CameraBox, FileInfo> StopRecordAll(Form form)
        {
            Dictionary<CameraBox, FileInfo> dict = new Dictionary<CameraBox, FileInfo>();
            foreach (CameraBox cam in cList)
            {
                if (cam.ParentForm == form)
                {   // Consider to use BeginInvoke Here to Save Time
                    FileInfo finfo;
                    if (cam.InvokeRequired) finfo = (FileInfo)cam.Invoke((Func<FileInfo>)delegate() { return cam.StopRecord(); });
                    else finfo = cam.StopRecord();
                    if (finfo != null) dict.Add(cam, finfo);
                }
            }
            if (dict.Count == 0) { MessageBox.Show("No CameraBox in this form !", "Nothing to Play"); return null; } else return dict;
        }
        #endregion
        #endregion

    }
}
